package beerAgent;

import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.util.ArrayList;
import java.util.List;

import evolutionaryLoop.Population;
import evolutionaryLoop.selectionMechanisme.FitnessSelection;
import evolutionaryLoop.selectionMechanisme.RankSelection;
import evolutionaryLoop.selectionMechanisme.SigmaSelection;
import evolutionaryLoop.selectionMechanisme.Tournament;
import evolutionaryLoop.selectionProtocol.FullGenerationReplacement;
import evolutionaryLoop.selectionProtocol.GenerationMixing;
import evolutionaryLoop.selectionProtocol.OverProduction;
import evolutionaryProblems.Phenotype;
import evolutionaryProblems.Problem;
import genotype.BeerGenotype;
import gui.GUIFrame;
import gui.LineChart;

public class BeerProblem extends Problem<BeerParameters> {

//	private BeerParameters parameters;
	private BeerProblem problem;
	private BeerSettingPanel settingPanel; 

	public static void main(String[] args) {
		new BeerProblem();
//		problem.gui.setVisible(true);
	}
	public BeerProblem(){
//		super(parameters)
		problem = this; 
		this.initialise();
		
	}
	
	@Override
	protected Population generatePopulation(){
		List<Phenotype> beerList = new ArrayList<Phenotype>(parameters.getPopulationSize()); 
		for (int i = 0; i < parameters.getPopulationSize(); i++) {
			BeerPhenotype phen = (BeerPhenotype) new BeerGenotype(parameters.getNetworkLayout(), parameters).evolveGenotype();
			beerList.add(phen);
			//System.out.println("fitness: " + phen.getFitness());
		}
		return new Population(beerList); 
	}

	@Override
	protected void initGUI() {
		guiFrame = new GUIFrame(this); 
		
		settingPanel = new BeerSettingPanel(problem, parameters); 
		settingPanel.showDefaultParameters(); 
		guiFrame.addSettingPanel(settingPanel); 
		
		lineChart = new LineChart();
		guiFrame.addLineChart(lineChart); 
		
		gameModel = new BeerGameModel(guiFrame, parameters); 
		guiFrame.addGamePanel(gameModel.getGamePanel());
		
		guiFrame.pack(); 
		guiFrame.repaint(); 
	}

	@Override
	protected void initParameters() {
		parameters = new BeerParameters();
		int[] nofNeuronsPerLayer = {5,2,2};
		
		parameters.setMinWeight(-5.0);
		parameters.setMaxWeight(5.0);
		parameters.setMinGain(1.0);
		parameters.setMaxGain(5.0);
		parameters.setMinTimeCons(1.0);
		parameters.setMaxTimeCons(2.0);
		parameters.setMinBias(-10.0);
		parameters.setMaxBias(0.0);
		parameters.setNofMaps(2);
		parameters.setMaxNumberOfIterations(1000); // generations
		parameters.setIterations(565); // moves per map
		parameters.setWidth(30); 
		parameters.setHeight(15); 
		
		parameters.setMutationRate(0.1); 
		parameters.setCrossoverRate(0.9); 
		parameters.setNumOfChildenToBeGenerated(100); 
		parameters.setPopulationSize(50); 
		parameters.setElitims(1);
//		parameters.setViewMap(false);
//		parameters.setGui(gui);
//		parameters.setTimePerFrame(500);
		parameters.setNetworkLayout(nofNeuronsPerLayer);
		parameters.setCulling(0);
		parameters.setCrossoverPoints(1); 
		parameters.setAdultSelectionProtocol(new OverProduction(parameters)); 
		parameters.setParenetSelectionMechanism(new SigmaSelection()); 
//		parameters.setParenetSelectionMechanism(new Tournament(0.05, 10, new SigmaSelection())); 
//		parameters.setParenetSelectionMechanism(new Tournament(0.05, 5, new SigmaSelection())); 
//		parameters.setParenetSelectionMechanism(new RankSelection());
//		parameters.setParenetSelectionMechanism(new FitnessSelection());
		parameters.setFitnessFunction(new BeerFitnessFunction(parameters)); 
		
		FileSystem fileSys = FileSystems.getDefault();
		String sep = fileSys.getSeparator();
		parameters.setWriteStatistics("BeerProblem" + sep + "Project4" + sep + "Beer ");
	}
	
	@Override 
	public void startSimulation(){
		parameters.setFitnessFunction(new BeerFitnessFunction(parameters));
		super.startSimulation(); 
	}
	public void killSimulation(){
		super.killSimulation();
		parameters.setFitnessFunction(new BeerFitnessFunction((BeerParameters) parameters)); 
	}


}
